package ctxmenu

import (
	"gmap-backend/internal/config"
	"gmap-backend/internal/server/manager"
	"gmap-backend/internal/server/vo"
	"gmap-backend/internal/util/pathutil"
	"path/filepath"
	"strings"
)

var excludeProtocols = []string{
	"cp://",
	"cppath://",
	"cmd://",
	"cmdp://",
	"start://",
}

var singlePartProtocols = []string{
	"file://",
	"dir://",
	"cmdopen://",
}

var doublePartProtocols = []string{
	"openas://",
	"openby://",
	"diropenby://",
	"openin://",
}

func blankResp() *vo.CtxMenuResp {
	return &vo.CtxMenuResp{Items: []vo.CtxMenuItem{}}
}

func LoadCtxMenu(appConfig *config.AppConfig, req *vo.PathReq, bins [][]byte) *vo.CtxMenuResp {
	if "" == strings.TrimSpace(req.Path) && "" == strings.TrimSpace(req.CtxDir) {
		return blankResp()
	}

	// 如果符合排除的协议，直接返回空结果
	for _, protocol := range excludeProtocols {
		if strings.HasPrefix(req.Path, protocol) {
			return blankResp()
		}
	}

	// file、dir、cmdopen协议
	noPrototolPath := manager.TrimPrefixProtocol(req.Path)
	for _, protocol := range singlePartProtocols {
		if strings.HasPrefix(req.Path, protocol) {
			return createResultForCandidatePath(noPrototolPath, req.CtxDir)
		}
	}

	// openas、openby、diropenby、openin协议
	parts := strings.Split(noPrototolPath, "@@")
	valid := strings.Contains(noPrototolPath, "@@") && len(parts) >= 2 && "" != strings.TrimSpace(parts[0])
	for _, protocol := range doublePartProtocols {
		if valid && strings.HasPrefix(req.Path, protocol) {
			return createResultForCandidatePath(strings.TrimSpace(parts[0]), req.CtxDir)
		}
	}

	// 是网址
	if strings.HasPrefix(req.Path, "http://") || strings.HasPrefix(req.Path, "https://") {
		return createResultForWebsite(req.Path)
	}

	// 增加文件路径判断
	if tmp := createResultForCandidatePath(noPrototolPath, req.CtxDir); len(tmp.Items) > 0 {
		return tmp
	}

	// 其他协议，只能复制地址，且地址不能去掉协议部分
	return &vo.CtxMenuResp{
		Items: []vo.CtxMenuItem{
			{
				Title: "复制地址",
				Url:   "cp://" + req.Path,
			},
		},
	}
}

func createResultForWebsite(path string) *vo.CtxMenuResp {
	return &vo.CtxMenuResp{
		Items: []vo.CtxMenuItem{
			{
				Title: "打开",
				Url:   path,
			},
			{
				Title: "打开方式",
				Url:   "openas://" + path,
			},
			{
				Title: "复制网址",
				Url:   "cp://" + path,
			},
		},
	}
}

func createResultForCandidatePath(path string, ctxDir string) *vo.CtxMenuResp {
	parsePathResult := pathutil.ParseValidPath(path, ctxDir)
	if !parsePathResult.Succ {
		return blankResp()
	}
	if parsePathResult.File {
		return createResultForFile(parsePathResult.ValidPath)
	}
	return createResultForDir(parsePathResult.ValidPath)
}

func createResultForDir(path string) *vo.CtxMenuResp {
	items := []vo.CtxMenuItem{
		{
			Title: "打开",
			Url:   "file:///" + path,
		},
		{
			Title: "打开所在目录",
			Url:   "dir://" + path,
		},
		{
			Title: "打开命令提示符",
			Url:   "cmdopen://" + path,
		},
		{
			Title: "复制全路径",
			Url:   "cppath://" + path,
		},
	}
	if dir := filepath.Dir(path); filepath.Clean(path) != dir {
		items = append(items, vo.CtxMenuItem{
			Title: "复制所在目录",
			Url:   "cppath://" + dir,
		})
	}
	items = append(items, vo.CtxMenuItem{
		Title: "复制目录名",
		Url:   "cp://" + filepath.Base(path),
	})
	return &vo.CtxMenuResp{
		Items: items,
	}
}

func createResultForFile(path string) *vo.CtxMenuResp {
	dir := filepath.Dir(path)
	items := []vo.CtxMenuItem{
		{
			Title: "直接运行",
			Url:   "file:///" + path,
		},
		{
			Title: "打开方式",
			Url:   "openas://" + path,
		},
		{
			Title: "打开所在目录",
			Url:   "dir://" + path,
		},
		{
			Title: "打开命令提示符",
			Url:   "cmdopen://" + dir,
		},
		{
			Title: "复制全路径",
			Url:   "cp://" + path,
		},
		{
			Title: "复制所在目录",
			Url:   "cp://" + dir,
		},
		{
			Title: "复制文件名",
			Url:   "cp://" + filepath.Base(path),
		},
	}
	return &vo.CtxMenuResp{
		Items: items,
	}
}
